from khronos import *
from khronos.extras.components import *

class Queue(Atomic):
    # store queue size along time
    size = TSeriesAttr(storing=True, timescale=HOUR, name="size")
    
    content = []
    def status(self):
        return str(self.content)
        
    def initializer(self):
        # discard previous values and initialize size to zero
        Queue.size.initialize(self, 0)
        self.content = []
        
    def append(self, obj):
        self.content.append(obj)
        self.size += 1 # data collection
        
    def next(self):
        obj = self.content.pop(0)
        self.size -= 1 # data collection
        return obj
        
    def finalizer(self):
        # retrieve the statistic collector
        stat = Queue.size.stat(self)
        p = Plotter("Plotting example", rows=2, cols=3)
        stat.pie_chart(plotter=p)
        stat.bar_chart(plotter=p)
        stat.pareto_chart(plotter=p)
        stat.histogram(plotter=p)
        stat.box_plot(plotter=p)
        stat.run_chart(plotter=p)
        
class Producer(Atomic):
    @chain
    def initializer(self):
        queue = self.find(".queue")
        rng = self.get_rng()
        while True:
            yield rng.uniform(5, 10) * MINUTE
            queue.append(rng.choice("abcdefgh"))
            
class Consumer(Atomic):
    @chain
    def initializer(self):
        queue = self.find(".queue")
        rng = self.get_rng()
        while True:
            yield rng.uniform(5, 10) * MINUTE
            try:
                queue.next()
            except IndexError:
                continue
                
def build_model(): 
    return Composite("root", children=[Queue(name="queue"), Producer(), Consumer()])
    
def build():
    k = Khronos(build_model())
    return k, k.model
    
k, m = build()

def main():
    k, m = build()
    k.single_run(DAY)
    
